<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <link href="main.css" rel="stylesheet" type="text/css"/>
    <script src='jquery.js'></script>
</head>
<body>


<div class="notification sticky hide">
    <p id="content"></p>
    <a class="close" href="javascript:"> <img src="/icon-close.png"/></a>
</div>
<div>
    <textarea id="online_box"
              style="margin-top: 20px; width: 80%;height: 500px; clear: both; display: inherit; margin-bottom: 20px;"></textarea>
    <button class="send">发送</button>
</div>


<script>
    $(document).ready(function () {
        let lockReconnect = false;//避免ws重复连接
        let ws = null;//判断当前浏览器是否支持WebSocket
        let wsUrl = "wss://socket.uxuj.cn:4333/wss";
        let uid = "crm_112233_app";
        let to = "crm_112233_web";

        //连接ws
        createWebSocket(wsUrl);

        function createWebSocket(url) {
            try {
                if ("WebSocket" in window) {
                    ws = new WebSocket(url);
                }
                initEventHandle();
            } catch (e) {
                console.log(e);
            }
        }

        function initEventHandle() {
            ws.onclose = function () {
                consoleMsg("连接关闭");
                reconnect(wsUrl);
            };
            ws.onerror = function () {
                consoleMsg("连接错误");
                reconnect(wsUrl);
            };
            ws.onopen = function () {
                ws.send(JSON.stringify({type: "login", "uid": uid}));
                heartCheck.reset().start(); //心跳检测重置
            };
            ws.onmessage = function (event) {
                let json_data = JSON.parse(event.data);
                if (json_data.type === "logout") {
                    consoleMsg("您已在其他设备登录，您已被踢下线");
                    lockReconnect = true;
                    heartCheck.reset().reset();
                    ws.close();
                } else if (json_data.type === "ping") {
                    consoleMsg(json_data);
                    heartCheck.reset().start();
                } else {
                    consoleMsg(json_data);
                    heartCheck.reset().start();
                }
            };
        }

        // 监听窗口关闭事件，当窗口关闭时，主动去关闭websocket连接，防止连接还没断开就关闭窗口，server端会抛异常。
        window.onbeforeunload = function () {
            ws.close();
        };

        // 重新连接
        function reconnect(url) {
            consoleMsg("尝试重新连接...");
            if (lockReconnect) {
                consoleMsg("重连失败");
                return;
            }
            lockReconnect = true;
            setTimeout(function () {     //没连接上会一直重连，设置延迟避免请求过多
                createWebSocket(url);
                lockReconnect = false;
            }, 2000);
        }

        //心跳检测
        let heartCheck = {
            timeout: 5000,        //1分钟发一次心跳
            timeoutObj: null,
            serverTimeoutObj: null,
            reset: function () {
                clearTimeout(this.timeoutObj);
                clearTimeout(this.serverTimeoutObj);
                return this;
            },
            start: function () {
                let self = this;
                this.timeoutObj = setTimeout(function () {
                    //这里发送一个心跳，后端收到后，返回一个心跳消息，
                    //onmessage拿到返回的心跳就说明连接正常
                    ws.send(JSON.stringify({type: "ping"}));
                    self.serverTimeoutObj = setTimeout(function () {//如果超过一定时间还没重置，说明后端主动断开了
                        ws.close();     //如果onclose会执行reconnect，我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
                    }, self.timeout)
                }, this.timeout)
            }
        };

        //发送
        $(".send").click(function () {
            ws.send(JSON.stringify({type: "publish", "to": to, "content": "test"}));
        });

        function consoleMsg(msg) {
            console.log(new Date().toLocaleString(), msg);
            let online_box = $("#online_box");
            online_box.val(online_box.val() + new Date().toLocaleString() + "  " + JSON.stringify(msg) + "\n");
        }
    });
</script>
</body>
</html>
